package mashibing.freshman.class05;

import java.util.HashSet;

/**
 * 位图很省，比Hash表节省32位
 */
public class Code02_BitMap2 {

	// 这个类的实现是正确的
	public static class BitMap {

		private long[] bits;

		// 初始化，给最大值：需要几个64位
		public BitMap(int max) {
			// (max + 64) >> 6 = (max + 64)/2^6 = (max + 64)/64
			bits = new long[(max + 64) >> 6];
		}
		// 加一个数，将它放到数组的第几位
		public void add(int num) {
			// num % 64 = num & 63
			bits[num >> 6] |= (1L << (num & 63));
		}
		// 减一个数，将它从数组中去掉
		public void delete(int num) {

			bits[num >> 6] &= ~(1L << (num & 63));
		}
		// 是否包含这个数
		public boolean contains(int num) {

			return (bits[num >> 6] & (1L << (num & 63))) != 0;
		}

	}

	/**
	 * 我写的:打印一个64位的二进制
	 * @param num
	 */
	public static void print64B(long num) {
		for (int i = 63; i >= 0; i--) {
			// num的第i位【二进制】和 1 << i 的第i位【二进制】进行&位运算
			System.out.print((num & (1L << i)) == 0 ? "0" : "1");//查看对应的位是否为1
		}
		System.out.println();
	}

	public static void main(String[] args) {
		print64B(3);
		// num % 64 = num & 63
		int a = 2141555;
		System.out.println(a % 64);
		System.out.println(a & 63);

		BitMap bitMap1 = new BitMap(10);
		//bitMap1.add(1);
		bitMap1.add(63);
		System.out.println(bitMap1.contains(10));
		System.out.println(bitMap1.bits.length);
		System.out.println(bitMap1.bits[0]);

		System.out.println("测试开始！");
		int max = 10000;
		BitMap bitMap = new BitMap(max);
		HashSet<Integer> set = new HashSet<>();// 位图
		int testTime = 10000000;
		for (int i = 0; i < testTime; i++) {
			int num = (int) (Math.random() * (max + 1));
			double decide = Math.random();
			// 前三分之一测试 +
			if (decide < 0.333) {
				bitMap.add(num);
				set.add(num);
			} else if (decide < 0.666) {// 中间的三分之一测试-
				bitMap.delete(num);
				set.remove(num);
			} else {// 后三分之一测试包含
				if (bitMap.contains(num) != set.contains(num)) {
					System.out.println("Oops!");
					break;
				}
			}
		}
		for (int num = 0; num <= max; num++) {
			if (bitMap.contains(num) != set.contains(num)) {
				System.out.println("Oops!");
			}
		}
		System.out.println("测试结束！");
	}

}
